import os, re, json, time
import logging
from pathlib import Path
import requests
import pandas as pd
from typing import Optional, Dict, List
from config import MODEL_CONFIG, GUIDE_FILES, LEXICON, SOCRE_PROMPTS,SALES_SCRIPT

logger = logging.getLogger('llm_manager')


class LLMManager:
    def __init__(self):
        self.api_key = MODEL_CONFIG["api_key"]
        self.base_url = MODEL_CONFIG["base_url"]
        self.model = MODEL_CONFIG["model"]
        self.temperature = MODEL_CONFIG["temperature"]
        self.top_p = MODEL_CONFIG["top_p"]
        self.max_tokens = MODEL_CONFIG["max_tokens"]
        self.max_retries = MODEL_CONFIG["max_retries"]
        self.retry_sleep = MODEL_CONFIG["retry_sleep"]
        self.max_chars = MODEL_CONFIG["max_chars"]
        self.force_stream = MODEL_CONFIG.get("force_stream", False)  # 是否强制使用流式模式
        self.headers = {
            'Authorization': f'Bearer {self.api_key}',
        'Content-Type': 'application/json'
    }

    def _call_llm(self, prompt: str) -> Optional[str]:
        """内部方法：调用大模型API（自动适配流式/非流式模式）"""
        data = {
            "model": self.model,
            "messages": [{'role': 'user', 'content': prompt}]
        }
        
        # 根据配置决定是否使用流式模式
        if self.force_stream:
            data["stream"] = True

        try:
            response = requests.post(
                f'{self.base_url}/chat/completions',
                headers=self.headers,
                json=data,
                stream=self.force_stream  # 根据配置启用流式接收
            )
            
            if response.status_code == 200:
                if self.force_stream:
                    # 处理流式响应
                    full_content = ""
                    for line in response.iter_lines():
                        if line:
                            line_str = line.decode('utf-8')
                            if line_str.startswith('data: '):
                                data_str = line_str[6:]  # 移除 'data: ' 前缀
                                if data_str.strip() == '[DONE]':
                                    break
                                try:
                                    chunk = json.loads(data_str)
                                    if 'choices' in chunk and len(chunk['choices']) > 0:
                                        delta = chunk['choices'][0].get('delta', {})
                                        content = delta.get('content', '')
                                        if content:
                                            full_content += content
                                except json.JSONDecodeError:
                                    continue
                    return full_content.strip() if full_content else None
                else:
                    # 处理非流式响应
                    result = response.json()
                    return result['choices'][0]['message']['content'].strip()
            else:
                logger.error(f"LLM请求错误: {response.status_code}, {response.text}")
                return None
                
        except Exception as e:
            logger.error(f"LLM交互异常: {str(e)}")
            return None

    def clean_text(self, text: str) -> Optional[str]:
        """清理文本内容"""
        prompt = SOCRE_PROMPTS["clean_text"].format(text=text)
        return self._call_llm(prompt)

    # def extract_business_info(self, text: str) -> Optional[Dict]:
    #     """提取业务信息（旧版，已废弃）"""
    #     prompt = SOCRE_PROMPTS["extract_business_info"].format(text=text)
    #     messages = [{'role': 'user', 'content': prompt}]
    #     result_str = self._post_chat(messages)
    #     if result_str:
    #         try:
    #             return json.loads(result_str)
    #         except json.JSONDecodeError:
    #             logger.warning("业务信息格式解析失败")
    #             return None
    #     return None
    
    def extract_business_info(self, text: str) -> Optional[str]:
        """
        生成会话概述
        返回简短的文本描述，如果失败或无有效信息则返回固定描述
        """
        if not text or not text.strip():
            return "无有效业务信息"
        
        prompt = SOCRE_PROMPTS["extract_business_info"].format(text=text)
        messages = [{'role': 'user', 'content': prompt}]
        result_str = self._post_chat(messages)
        
        if result_str:
            # 清理可能的格式标记
            summary = result_str.strip()
            # 移除可能的 markdown 标记
            summary = summary.replace('```', '').replace('**', '')
            # 移除开头的 "概述：" 等标签
            if summary.startswith(('概述：', '概述:', '摘要：', '摘要:')):
                summary = summary.split('：', 1)[-1].split(':', 1)[-1].strip()
            
            # 限制长度
            if len(summary) > 200:
                summary = summary[:200] + "..."
            
            # 如果为空或过短，返回默认值
            if not summary or len(summary) < 5:
                return "无有效业务信息"
            
            return summary
        else:
            return "无有效业务信息"

    def process_text(self, raw_text: str) -> Optional[Dict]:
        

        """
        对外提供的统一方法：先清理文本，再生成会话概述，最后评分
        
        返回格式：
        {
            "business_info": str,  # 会话概述（字符串），如"客户办理宽带业务..."
            "score_result": dict   # 评分结果（字典）
        }
        """
        # 第一步：清理文本
        cleaned = self.clean_text(raw_text)
        if not cleaned:
            logger.warning("文本清理失败，将使用原始文本继续处理")
            cleaned = raw_text  # 使用原始文本作为备选
        
        # 第二步：生成会话概述（现在返回字符串而不是字典）
        business_info = self.extract_business_info(cleaned)
        if not business_info:
            business_info = "无有效业务信息"

        # 第三步：评分功能
        score_result = self.session_score(raw_text)
        if not score_result:
            logger.error("评分失败")
            return None
        
        # 合并结果
        return {
            "business_info": business_info,  # 字符串类型
            "score_result": score_result      # 字典类型
        }

    def _load_guidelines(self) -> List[str]:
        """加载营销引导话术库"""
        texts = []
        for p in GUIDE_FILES:
            if not p.exists():
                logger.warning(f"未找到话术库：{p}")
                continue
            try:
                df = pd.read_excel(p, dtype=str)
                for col in df.columns:
                    col_vals = df[col].astype(str).fillna("").tolist()
                    for v in col_vals:
                        v = str(v).strip()
                        if v and v.lower() not in ("nan", "none") and len(v) >= 2:
                            texts.append(v)
            except Exception as e:
                logger.warning(f"读取话术库失败 {p}: {e}")
        # 去重清洗
        seen = set()
        uniq = []
        for t in texts:
            t2 = t.replace("\u3000", " ").replace("  ", " ").strip()
            if t2 not in seen:
                seen.add(t2)
                uniq.append(t2)
        return uniq

    def _load_script(self) -> List[str]:
        """加载营销话术"""
        if not SALES_SCRIPT.exists():
            logger.warning(f"未找到营销话说：{SALES_SCRIPT}")
            return []
        items = []
        for line in SALES_SCRIPT.read_text(encoding="utf-8").splitlines():
            t = line.strip()
            if t:
                items.append(t)
        return sorted(set(items), key=lambda x: len(x), reverse=True)

    def _load_lexicon(self) -> List[str]:
        """加载业务底表"""
        if not LEXICON.exists():
            logger.warning(f"未找到业务底表：{LEXICON}")
            return []
        items = []
        for line in LEXICON.read_text(encoding="utf-8").splitlines():
            t = line.strip()
            if t:
                items.append(t)
        return sorted(set(items), key=lambda x: len(x), reverse=True)
        
    def _post_chat(self, messages: List[Dict]) -> Optional[str]:
        """调用大模型API（自动适配流式/非流式模式）"""
        payload = {
            "model": self.model,
            "messages": messages,
            "temperature": self.temperature,
            "top_p": self.top_p,
            "max_tokens": self.max_tokens
        }
        
        # 根据配置决定是否使用流式模式
        if self.force_stream:
            payload["stream"] = True
            
        for attempt in range(1, self.max_retries + 1):
            try:
                resp = requests.post(
                    f"{self.base_url}/chat/completions",
                    headers=self.headers,
                    json=payload,
                    timeout=120,
                    stream=self.force_stream  # 根据配置启用流式接收
                )
                if resp.status_code == 200:
                    if self.force_stream:
                        # 处理流式响应
                        full_content = ""
                        for line in resp.iter_lines():
                            if line:
                                line_str = line.decode('utf-8')
                                if line_str.startswith('data: '):
                                    data_str = line_str[6:]  # 移除 'data: ' 前缀
                                    if data_str.strip() == '[DONE]':
                                        break
                                    try:
                                        chunk = json.loads(data_str)
                                        if 'choices' in chunk and len(chunk['choices']) > 0:
                                            delta = chunk['choices'][0].get('delta', {})
                                            content = delta.get('content', '')
                                            if content:
                                                full_content += content
                                    except json.JSONDecodeError:
                                        continue
                        return full_content.strip() if full_content else None
                    else:
                        # 处理非流式响应
                        return resp.json()["choices"][0]["message"]["content"]
                logger.warning(f"API {resp.status_code}: {resp.text[:200]}")
            except Exception as e:
                logger.warning(f"调用失败（第{attempt}次）：{e}")
            time.sleep(self.retry_sleep * attempt)
        return None

    def _sanitize_json_str(self, s: str) -> str:
        """清洗JSON字符串"""
        s = s.strip()
        s = re.sub(r"^```(?:json)?\s*", "", s, flags=re.I)
        s = re.sub(r"\s*```$", "", s, flags=re.I)
        s = s.replace("“", "\"").replace("”", "\"").replace("‘", "'").replace("’", "'")
        return s

    def session_score(self, raw_text: str) -> Optional[Dict]:
        """评分核心方法"""
        if not raw_text:
            return None
        
         # 读取话术库
        guidelines = self._load_guidelines()
        # 压缩话术库
        guidelines_compact = self._compact_guidelines(guidelines)
        # 构建提示词
        messages = self._build_scoring_messages(raw_text, guidelines_compact)
        # 调用模型
        response = self._post_chat(messages)
        if not response:
            return None

        # 解析结果
        try:
            json_str = self._sanitize_json_str(response)
            logger.debug(json_str)
            return json.loads(json_str)
        except json.JSONDecodeError as e:
            logger.error(f"解析评分结果失败：{e}，原始响应：{response[:200]}")
            return None
    

    def _compact_guidelines(self, lines: List[str], max_chars=4000, max_items=120) -> str:
        """压缩话术库为要点清单"""
        out, total = [], 0
        for s in lines[:max_items]:
            s = s.replace("\n", " ").strip("；; ")
            if not s:
                continue
            candidate = s if s.endswith(("。", "；", ";", ".")) else s + "；"
            if total + len(candidate) > max_chars:
                break
            out.append(candidate)
            total += len(candidate)
        return "".join(out) if out else "（暂无可用的话术要点）"

    def _build_scoring_messages(self, raw_dialog: str, guidelines_compact: str) -> List[Dict]:
        """构建评分用的提示词消息"""
        lexicon_items = self._load_lexicon()
        lexicon_block = "、".join(lexicon_items[:300])
        
        sale_script = self._load_script()
        sale_script_block = "、".join(sale_script[:300])

        rubric = SOCRE_PROMPTS["scoring_rubric"]
        schema = SOCRE_PROMPTS["output_schema"]
        system_rules = SOCRE_PROMPTS["scoring_system_rules"]
        
        user_content = f"""业务底表（节选）：{lexicon_block}
营销引导话术库：{sale_script_block}
原始对话：{raw_dialog[:self.max_chars]}

评分指导原则：
1. 服务态度评分：只要营业员使用了基本礼貌用语（如"您好"、"谢谢"、"不客气"等），就应给予1-2分；主动询问、耐心解答可得2-4分；进一步表现出同理心和积极性可得4-5分。
2. 沟通能力评分：只要营业员能够基本表达意思，就应给予1-2分；如果表达清晰、信息完整，应给予3-4分；结构有序、逻辑清晰可得4-5分。
3. 问题解决评分：采用较为宽松的评分方式，只要营业员提供了解决方向或基本方案，就应给予2-3分；如果给出具体步骤，应给予3-4分；问题完全解决或提供明确路径可得4-5分。

{rubric}
{schema}"""
        
        return [
            {"role": "system", "content": system_rules.strip()},
            {"role": "user", "content": user_content.strip()}
        ]

    

if __name__ == "__main__":
    """测试方法"""
    # 初始化管理器
    llm_manager = LLMManager()
    
    # 测试用例
    test_text = """
        0: 上网不不影响吧，
        1: 是携转呗，
        2: 那他他现在不想现，
        2: 他现在不想携转，
        1: 他签字，
        0: 就如果写转不到就行。
        2: 他现他不想写转，
        2: 那到时候写转，
        2: 如果有问题，
        2: 我再给他取消，
        2: 是不是也行啊，
        2: 那就行，
        2: 那就行。
        2: 好的，
        2: 嗯，
        2: 不聊嗯，
        1: 好嘞好嘞，
        1: 不用取消。
        1: 好嘞，
        1: 那我懂了好嘞，
        1: 拜拜。
        1: 那给我整的挺紧张。
        0: 你说可以，
        2: 到时候如果携转有问题，
        2: 我们这边也可以给你取消。
        1: 因为我给你钱，
        0: 正好我我发短信就不行呗，
        2: 发短信不他不一定。
        2: 他就是我们现在系统吧，
        2: 他可能出现两种情况。
        2: 因为我们现在现在这个靓号系统还不太稳定点，
        1: 麻烦那个你签字就行，
        1: 不是问问。
        2: 然后你要携转的话，
        2: 如果你转不出，
        2: 我这边可以单方面帮你把这个业务给取消了，
        2: 就是不耽误你的事行。
        3: 哎，
        3: 为啥呢？
        3: 啊，
        3: 有朋友，
        0: 我本来过几月是我想转走，
        0: 不也可以转走吗？
        3: 那就行，
        0: 过户不随便过吗？
        1: 过户随便过，
        0: 你能查出来，
        0: 我有我有没有这号协议吗？
        1: 嗯，
        1: 稍等，
        1: 我看人不查了，
        0: 我不卡了，
        1: 着急着着急，
        3: 就是嗯好啊。
        2: 然后如果是携转有任何问题的话，
        2: 我这边能帮你取消这个两房协议，
        2: 你随时找过来就行。
        1: 太贵呢，
        3: 别问了，
        1: 他随时可以取消了。
        1: 嗯，
        2: 就我也给打电话，
        1: 我打俩电话就给你问清楚。
        1: 对，
        1: 不然以后咱们之间就各有罗乱，
        1: 不好真棒。
        3: 嗯，
        3: 行啊，
        0: 那本来就没有靓号协议，
        0: 你到你那能给我来个靓号协议。
        0: 对，
        1: 不完事儿完事儿了事儿了。
        3: 嗯，
        1: 你问他基本都是 a 你说再呼我一个。
        1: 好，
        1: 你补较意义在是一老鼠。
        1: 嗯，
        1: 我这个我想查一下，
        4: 我这个电费不是手续费，
        4: 现在这月我能缴扣五十九块钱，
        4: 不看哈，
        4: 你接忙过去了，
        4: 幺三三二二幺五五六二九，
        4: 五六二九。
        1: 嗯，
        1: 对，
        1: 五六二九，
        1: 这一共花多少钱？
        1: 不是，
        1: 就是八月份的，
        4: 你看八月份的，
        4: 看八月份的嗯，
        4: 八月份就是改过来的嘛，
        4: 说花多少钱？
        1: 八个花五十九。
        1: 嗯，
        1: 怎么到了呢？
        1: 对呀，
        4: 我所以我就来问了了三十九，
        4: 他跑了五十九了，
        4: 你咋说？
        4: 我昨天我一看你不对劲呢，
        4: 我说得了，
        4: 原先是有个联系人，
        4: 要我换个手机，
        4: 那号都没了。
        4: 我说得了，
        4: 直接来吧，
        2: 之前有个给你做的政企二十元赠费，
        4: 不是啊，
        4: 不是正费啊，
        1: 我那什么五五十块五十九块钱套餐。
        1: 对呀，
        2: 他给你做了一个类似折扣的东西，
        2: 就每个月帮你减二十块钱。
        2: 从八月份开始，
        2: 这个减二十块钱的应该是到期了。
        1: 所以他现在到期了。
        4: 他是原先是按照那个套餐，
        4: 咱们家电视不用了，
        4: 他就扣了那钱，
        4: 扣二十块钱。
        4: 所以说三十九你那边是这么，
        1: 那可能你这个就是到期了到期，
        4: 我那电视实付我没用啊，
        1: 原先套餐到期，
        2: 了办什么证呢？
        1: 嗯，
        1: 咱身份证我还没法进，
        1: 我给你查，
        2: 反正我目前看就是你这个重疾的服务到期了。
        1: 我那天我搁哪看的这个二楼还是三房不大厅办理呃，
        4: 那呃宽带电视的完了，
        4: 电视死了没？
        3: 那他大学这个啊，
        1: 我这边还没法给你查具体的东西，
        1: 你要不你看身份证啊，
        4: 身份证我得要远件儿，
        2: 家里有人能给你送一下上，
        4: 那我办理电了嗯，
        3: 拔了好嘞，
        3: 二十分办公间说在梦上。
        1: 雪儿姐二三年八月份给的钱吗？
        1: 等会儿不忘说了，
        1: 哥哥，
        1: 他在我朋友，
        1: 你给他加吗？
        1: 不是加一个带身份证，
        2: 我就现在我能帮你问，
        1: 怎么去给你整呢？
        2: 那你整的时候还是得拿身份证原件整。
        1: 嗯，
        2: 雪儿姐，
        2: 你看我给你发微信了吗？
        1: 这你经他挣争取的中费二十元到期了，
        1: 再联系他那笔烦。
        1: 怎么等一下，
        1: 我看上次是你那是市场部同意延的，
        1: 也是是说这个就没有了。
        1: 我有这么大权利呢？
        1: 哎，
        1: 我你看看我的公众号，
        1: 他是没有了那个微信那个他要咋办？
        1: 你按文信那个你那是这样吗？
        1: 那我给了那手机卡加个还有一个个小时吗？
        1: 打你原来是那个吗？
        1: 五十九五十九百二十嗯三十九。
        1: 但是现在就那一年，
        1: 那就爷爷拿什么东西过来办，
        4: 拿个份证，
        1: 拿什份证，
        1: 手手五块块钱，
        1: 得交六十块钱的话费。
        1: 然后我们给你也有权限的一个政策才能们们己跟你们来的一样的。
        4: 那那和那个电视不发生关系了，
        1: 电视要花钱吗？
        4: 那电视原先就是原来拆除了了，
        4: 俺拆除了，
        4: 所以以那前就是五十九。
        4: 然后俺拆除了以后，
        4: 变成三十九的啊，
        1: 那现在还按三十九给你做呗。
        4: 我意思说你这不还按那个这个月给涨了，
        4: 又涨五十九去了。
        1: 那现在原来的那个优惠到期了，
        1: 那个优惠不两年，
        4: 那两年不是我电视，
        4: 始终也不看了，
        1: 不是跟电视啥关系，
        1: 已意，
        1: 现在你老是那电视啥意思啊，
        1: 电视有啥关系啊？
        4: 电视减，
        4: 前天就说是电视啊，
        4: 你说不看了，
        4: 那个电视视了，
        1: 说的七月二十寸跟那个电视二关系没有关系。
        1: 那原来本费有一个本片二十寸的，
        1: 到期了，
        4: 电视机，
        4: 我要电视，
        4: 要是咋看呢呢？
        1: 看的话就就充电了，
        1: 每电是一个月十块钱，
        1: 然后交一百块钱安装费，
        4: 就那回事儿，
        4: 我也没整明白，
        3: 都开户个，
        4: 那我拿那个身份证就可以了。
        4: 原件哈拿身份证，
        1: 我你拿身份证，
        1: 我只能保证你往外花三十九块钱，
        1: 然后咱家花高清的话，
        2: 就得每个再加十块钱，
        4: 就是三十九那样别的不用，
        4: 那我拿身份证来就行，
        4: 哈那我拿时间就过来，
        1: 麻烦给他。
        3: 没有来问一下，
        4: 你们现在最低价为多少手？
        1: 你号了二十一，
        3: 那个是这个就是改发卡就能吧，
        4: 那我就改了身份证。
        4: 哎呀，
        4: 拿事了。
        4: 好了，
        1: 刚才拿着了一过来吧。
        3: 好的，
        1: 你来一会上卫生间去，
        1: 我买个杆子，
        1: 嘴里的全裂了，
        1: 一说话都吗？
        3: 这个怎么走？
        1: 姐跟我说一下手机号吧，
        3: 幺零零啊，
        3: 咋么办？
        3: 哎，
        1: 那是这样了，
        1: 我的快乐到哪儿呢？
        1: 到哪，
        3: 那你就这个谢谢，
        3: 不知道是迁移，
        1: 我过户给您之后，
        1: 就之前的那个账单享法，
        1: 什么都没有了，
        1: 积分也没有了。
        1: 对我刚才看了一眼那地方三百多不够不够换。
        1: 对，
        1: 不够换一得满一千才一千都得换十块钱的话费差不多。
        3: 嗯，
        1: 你没有找到我两张卡，
        1: 你有的嗯联易支付那个你用吗？
        1: 正常都不用了，
        1: 我不那就取消不就完事了。
        1: 那你有时候有一有没有用的，
        1: 没有用乘分期。
        1: 哎，
        1: 你要把这些数条哦，
        1: 好，
        1: 我再再叫一个人，
        1: 你那边能能能忙吗？
        1: 我再叫一个，
        1: 再叫一个吧，
        1: 然后他那边还能干吗？
        1: 猪客户他没有权限点是吗？
        1: 客户就咱们这边有交一单是幺三的啊，
        1: 你要爸妈跟他说吧，
        3: 嗯在对他们嗯，
        1: 你咋的了，
        1: 这说的不要打宽了再说，
        1: 他来不选号动手张嘴啊，
        1: 没有东西吧，
        1: 把手反过来。
        1: 哎呀，
        1: 妈呀，
        1: 那个我先选号十号看好嗯，
        3: 学习啊。
        3: 对嗯，
        3: 好的嗯，
        3: 啊对，
        3: 就这个他写签名给我们。
        3: 对，
        3: 办理好，
        3: 我靠，
        3: 激很那么多编排，
        1: 把那个高中生会有一个短信，
        1: 你说退户好好好。
        3: 嗯，
        3: 是你不？
        1: 你这袜没穿呢，
        1: 你得穿着可得穿到过节上年了啊，
        1: 冻凉了不冻结了吗吗？
        1: 是的，
        1: 有的都是错挂的。
        1: 那个你脚底下量个长长的选号。
        1: 哎，
        1: 我我找找三天的，
        3: 不会，
        1: 我不影响你栽坏。
        1: 你好，
        1: 应该这个几个。
        3: 好，
        1: 你你也没跟他说，
        1: 你能不能多个心能写不写，
        1: 你能写两句，
        3: 还有很好有什么什么成绩协议啊？
        3: 嗯，
        3: 对不起，
        3: 间姐，
        1: 我又看了一眼，
        1: 你有一千个积分，
        1: 我给你换十块钱话费了啊，
        1: 就填到这个号了。
        3: 很多名字不是道，
        3: 现在是第二个对吧？
        3: 就一个呢三啊，
        3: 然后开户对呀，
        1: 几本零一个，
        1: 还有那个嗯基本变化。
        1: 九月十几号真天的见，
        1: 还是我也是前面这个好，
        1: 什么好，
        1: 啥概记录，
        1: 这个号不是靓号吧，
        1: 这一字嗯嗯，
        1: 我把门拿蛋白纸哦，
        3: 嗯没有哎，
        1: 填属的哈。
        1: 在那呀，
        1: 你在你以前有一点，
        1: 我说没这个，
        1: 我喜欢吃火锅肉，
        1: 吃的是零人，
        1: 那你要没换发几零。
        1: 我我记以前对对，
        3: 嗯嗯，
        1: 颜色四个号的，
        1: 八个号的，
        3: 明天。
        1: 对呀，
        1: 真的很麻烦，
        1: 十万十万出不来不多。
        3: 对，
        3: 然后呢好嘞，
        1: 现在在找人民运动姐，
        1: 咱们得一起拍个照。
        1: 您和姨姨在前礼在后交叉着来，
        1: 主要是你离那啥叫双腿，
        1: 等以二答对了，
        3: 还要看那个相关价设哦啊，
        1: 那可能就是阿哥同意的，
        3: 好烦吃，
        3: 后面没有你想吃也准，
        4: 你就早点转哈啊，
        1: 用不用弄。
        1: 你你你要是说我应该还是留一年就好，
        1: 因为那个就是你办的人，
        1: 你看嗯工厂管员要选号看迁，
        1: 然后然后怎么的，
        3: 刚河完找一下。
        1: 不是，
        1: 本说没要保存，
        1: 一年一年有这个人人已经发过一年，
        1: 不是过了，
        1: 他妈是哪里别忘理。
        1: 嗯，
        1: 对呀，
        1: 一年过去。
        1: 对对呀，
        1: 签签字就您和一个年都签上头写，
        1: 你下头给你，
        1: 你签也行，
        1: 把两名都是都得签呢啊，
        1: 可以了，
        1: 换换节也家交点不错，
        1: 快点过去啊。
        3: 他不能，
        1: 那他我我我他说办完，
        1: 他再看，
        1: 不愿意你交，
        1: 他不爱打人啊，
        1: 了解能民两个，
        1: 这个是我们刚才我的甲流呢。
        1: 没行，
        1: 没事，
        3: 看起哪。
        3: 嗯，
        3: 行，
        1: 给你们办，
        1: 老老保险的，
        1: 就这个事，
        1: 就这个颜色，
        1: 你哪个办办？
        1: 这是那个这这个姐完事儿了，
        1: 已经到楼下了。
        3: 对的，
        1: 那个这回是谁来呢？
        1: 喂，
        1: 哎我开玩笑了哈，
        1: 挂了嗯，
        1: 下来了，
        1: 两千斤，
        3: 你根本怎么了啊啊，
        1: 交班什么交话费，
        1: 交话费，
        1: 这个宽带费呗，
        1: 号码是多少？
        0: 没错了，
        0: 我给你说是那什么玩意儿，
        1: 身份证啊。
        1: 嗯，
        3: 他妈嗯嗯明天啊，
        2: 那还有个移动号，
        0: 哎，
        0: 在移动上要多麻烦呢。
        2: 手机号绑定绑定绑定，
        2: 现在我们有就是手机号加宽带号加一起才五十九。
        2: 然后移动号，
        2: 你那边能花多少钱，
        0: 你给我说这多少钱啊，
        2: 你移动话费那边能花多少钱？
        0: 花费十八呀，
        0: 这工费四八嗯有没有能超开的？
        0: 四十就五十八吗？
        0: 这个叫四十一斤五十八块钱一斤五十八，
        2: 他那边给你流量，
        1: 哪些批发素不？
        0: 嗯，
        0: 流量是七，
        1: 花费交多少交呃，
        1: 年龄算你先让他给你算你那边话费，
        2: 你那边他给你流量能交多少钱数，
        0: 这不一就一共少十八块钱吗？
        0: 顾顾费吗？
        2: 有流量没呀，
        1: 有啊，
        1: 有多多少流量啊，
        0: 十 g 的吧。
        0: 嗯，
        1: 十个 g 我们现在我们现在相当于给你四十二个 g 的流量，
        2: 三百分十普通啊啊两百多多少钱？
        0: 是多少兆的？
        2: 一百兆单宽吗？
        1: 两百一百兆单宽，
        0: 还有个高级是一百兆是不？
        0: 嗯，
        1: 我们那边要五十的话，
        2: 能给你提到三百张四十个 g 流量，
        2: 三百分钟通话，
        2: 三百兆宽带就给我一块钱。
        0: 这我这多掏一块钱，
        0: 完了掏一块钱。
        2: 那我们这给你提到三百兆的速度啊，
        0: 而且与这个与这个与这个有关系，
        0: 没与哪个有关系？
        0: 没那个一月十八块钱，
        2: 那个与与一个月十八块钱，
        2: 你那一个月十八块钱你就不交了。
        1: 嗯，
        2: 就这个手机号，
        2: 你移动多少号嗯，
        2: 移动手机号多少号，
        0: 你六三五幺三五多少？
        0: 幺四幺四幺四幺四幺六幺四八六幺五。
        2: 你这个手机号你就带着这个号号码给你不变，
        1: 嗯，
        2: 就转到我们电信来。
        2: 然后你就不用单独，
        2: 我又交一个四十，
        2: 我又每个月我交这个十八块钱，
        1: 就一下跟我们这都交五十九，
        2: 我们就是四十个四十二个 g 流量，
        2: 三百分钟通话，
        2: 然后宽带还能给你提速。
        2: 你说你刚才跟我说，
        2: 移动那边就给你十个 g 流量，
        2: 那四十二个 g 全是全国的流量，
        2: 就是不分省内省外这那的流流量。
        0: 嗯，
        2: 然后三百分钟通话，
        2: 他的通话指定也没我们多，
        2: 他通话大概在一二百分钟左右，
        0: 我认就够了。
        0: 我们那样交钱，
        2: 你一下交完多省劲儿啊，
        2: 多省事啊，
        2: 你以后直接交话费就行了，
        0: 你多多多掏一块，
        0: 我这号改过号不改号不不改，
        2: 你就多掏一块钱的事儿少，
        0: 这不能给你编，
        0: 那一块钱交给你这啊。
        2: 对呀，
        2: 你就每个月五十九你就固定，
        2: 你自己想交话费交话费，
        2: 你想来我们这儿交就来我们这儿交怎么交都行，
        0: 把话费那拿交都行，
        0: 像话费还是十八呗，
        0: 改四九了，
        1: 改改五十九了。
        2: 然后就是手机话费，
        2: 加上宽带费加在一起一共是五十九。
        2: 你他妈跟着脚什么事儿，
        2: 然后给的东西太多，
        1: 通话时长下面哦，
        0: 别改了，
        0: 我想我想干什么？
        0: 我想那个我够用，
        0: 小米这个是四十，
        1: 不就是差不多一年四百八呀，
        0: 我搅半年呢，
        0: 六个月的，
        1: 他是半小钱钱不够是吧？
        1: 二百四六个月，
        1: 二百四三月四十的话，
        3: 嗯，
        3: 哦没问题。
        1: 哎，
        1: 谢哎呀，
        0: 这屋这么凉，
        0: 这这这给给人那空调好啊，
        1: 交二百四十块钱，
        1: 我找你六十啊。
        1: 哎，
        1: 对对吗？
        3: 是尾好，
        1: 零钱不够了，
        2: 找多少钱找他六十讲完了，
        0: 这个没有没有零钱啊，
        1: 有零钱儿啊，
        1: 你有零钱没？
        1: 我看您现在那个还剩了十九块多，
        2: 你这里面话费还剩十九块七毛六。
        0: 嗯，
        1: 那材单费你有零钱了吗？
        1: 我没有，
        0: 你也没有零钱啊，
        0: 你说喝卡会呀，
        0: 看他有没有，
        1: 他那边更没有了。
        1: 他们那边不不收现金，
        0: 那怎么整，
        0: 你就预备点零钱啊，
        1: 有预备的那不够，
        1: 那预备少了。
        0: 那不是刚找出去了，
        1: 找找不是你预备少了，
        0: 你进去一千块钱零钱是不是就什么都有了？
        2: 真真不像你八万块八万人掌收五十押子，
        1: 快起来，
        1: 不能有换了。
        0: 我看看我看我这我得多交点，
        1: 你多交点啊啊，
        0: 多交那个，
        1: 那早才三十能多交点儿。
        1: 不是哦，
        0: 我看看啊，
        0: 这交叫二百四二百四都交一个月的，
        0: 交七个月的去不走海了吗？
        0: 是不四斤二百八吗？
        0: 二百八二百八，
        0: 你得加我二十块钱。
        0: 哎，
        1: 行，
        1: 找年二十，
        1: 找年二十。
        1: 对对对，
        1: 这用你收的吗？
        1: 对，
        1: 然后又收了小玉很玉，
        1: 小玉老有钱了，
        1: 是不啊？
        2: 我不知道为啥，
        2: 我每次一上这都是交费的，
        1: 多是你不来怎你都不下午下午吧啊，
        1: 给充二百八了啊。
        0: 好，
        0: 行，
        1: 哎呀，
        1: 呢，
        2: 他那个正儿肖姐，
        2: 她不有二百五十块钱，
        1: 还有二八，
        1: 还有二宝，
        1: 不是他欠我一百，
        1: 他还有有关喝销，
        1: 选什么希碗二百四。
        1: 嗯，
        1: 反正没事，
        1: 就所有人突然到我那里了，
        1: 我的天哪，
        1: 我知道的，
        1: 你那里都没有钱，
        1: 算我什么钱，
        1: 因为我的钱我他没有呀。
        1: 那就是前面那个反正多少年前都算我们携转，
        1: 就是你和那个明明啊，
        1: 明明不是十两块八，
        1: 我本来你的都有你儿子家。
        1: 嗯，
        1:  no，
        1: 昨天那个你这里 hello，
        1: 不要演出哈，
        0: 下下次交费什么钱嗯，
        0: 你给我写了下去。
        0: 对，
        0: 好了，
        0: 天你会写上下次缴费什么型？
        0: 哎，
        0: 好，
        1: 我带你写，
        0: 确实有。
        0: 那这些没有用的人，
        1: 暂时都说不上得，
        0: 十月份份可能想苦苦拆苦苦迁迁移，
        1: 我都闹死去了。
        2: 那我都撇好几次了，
        1: 我的个门钱永远都是可满了，
        0: 是吧？
        1: 我交二百八十元七个月嗯，
        1: 这样行，
        1: 不交二百八十元七个月宽带费。
        1: 嗯，
        1: 行不这样写？
        1: 不是我，
        0: 我还这下十交，
        0: 就是缴费日期是给我了。
        1: 你那天我不给你转了一百吗？
        2: 那一百里面有我的五十，
        1: 你自己的五十和公司的五十，
        1: 咱俩都平了，
        1: 咱俩这儿，
        1: 我把那二爸拿走了，
        1: 那那十块钱是怎么回？
        0: 是五五月份吧，
        0: 是不？
        0: 五月份，
        1: 我给你算算啊，
        1: 现在是九月份九月份，
        1: 你看九月份十月十一十二一月二月三月四月五月。
        1: 哎，
        1: 咋咋四四月到四月份是七月是是四四月四月到四月份，
        0: 四月十五号是吧，
        0: 今在是十七号了，
        0: 四月十七号啊，
        1: 你记一下四月十七号了，
        1: 快点好了。
        1: 哎，
        0: 好了，
        0: 就十七号缴费是吧，
        1: 咱俩没有账了吧，
        1: 不行，
        1: 这钱我也看不过，
        1: 你咋按看，
        1: 不如我怕沫，
        2: 我自己还赔钱，
        2: 你得上班赔点儿，
        1: 他老师会来撤门。
        1: 哎呀，
        1: 又另一个又没有口了，
        1: 又要扩容了。
        1: 我现在你款就安宽带，
        1: 等着点宽带的走九幺四幺四九三啊，
        1: 十岁了，
        3: 不知道没完成因费办理。
        1: 哎呦，
        1: 我说不太不太熟练，
        1: 这玩意就不想我爱用。
        1: 二十六天没关，
        1: 赶紧揣兜里，
        2: 别揣手里了，
        1: 一会儿料子活不到了。
    """
    
    # 处理文本
    result = llm_manager.process_text(test_text)
    
    # 打印结果
    if result:
        logger.info("处理结果：")
        import pprint
        pprint.pprint(result)
    else:
        logger.error("处理失败")